#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
    对pop3进行了封装，用于实现发送邮件，删除邮件的功能。
可能存在未知的bug。
    注意点：该类中 username,password,ssl均没有写get/set方法，
username,password属性的赋值在login()方法中,ssl属性赋值在
get_pop()中，特此注明，方便后续随GUI前端要求做相应改动。
    is_connecting方法中noop()测试存在bug,替换成了getwecome(),有待测试优化。
"""
import poplib
poplib._MAXLINE = 204800


class ClientPop:
    def __init__(self, host=None, port=None):
        self.__host = host
        self.__port = port
        self.__pop = None
        self.__ssl = None
        self.__username = None
        self.__password = None

    def set_host(self, host):
        self.__host = host

    def set_port(self, port):
        self.__port = port

    def set_username(self, username):
        self.__username = username

    def set_password(self, password):
        self.__password = password

    def get_host(self):
        return self.__host

    def get_port(self):
        return self.__port
    # host、port属性的get/set方法

    def get_pop(self, ssl=False):
        """
        根据ssl参数得到一个相应的pop连接，并赋予属性self.pop;
        :param ssl: 默认False
        :return: None
        """
        self.__ssl = ssl
        if not ssl:
            self.__pop = poplib.POP3(self.__host, self.__port)
        elif ssl:
            self.__pop = poplib.POP3_SSL(self.__host, self.__port)

    def is_connecting(self):
        """
        判读连接有无断开;
        :return: 没断开，返回(True,'Connecting...')
                 断开，返回(False,'错误信息')
        """
        try:
            self.__pop.getwelcome()
            return True, 'Connecting...'
        except Exception as err:
            return False, str(err)

    def hello(self):
        """
        向服务器打招呼
        :return: 返回(True/False,欢迎语/错误信息)
        """
        status = self.is_connecting()
        if status[0]:
            welcome = self.__pop.getwelcome()
            return True, welcome
        else:
            return False, status[1]

    def relogin(self):
        self.login(self.__username, self.__password)

    def login(self, username, password):
        """
        登陆pop服务器;
        :param username: String用户名
        :param password: String密码
        :return: (True/False,'success!'/error message)
        """
        self.__username = username
        self.__password = password
        status = self.is_connecting()
        if status[0]:
            try:
                self.__pop.user(username)
                self.__pop.pass_(password)
                return True, 'success!'
            except Exception as err:
                return False, str(err)
        else:
            return False, status[1]

    def reconnect(self):
        """
            此方法在get_pop()和login()方法被调用后方可调用，
        自动重新连接pop服务器;
        :return:(True/False,'success'/error message)
        """
        try:
            if self.__ssl:
                self.__pop = poplib.POP3_SSL(self.__host, self.__port)
            else:
                self.__pop = poplib.POP3(self.__host, self.__port)
            self.login(self.__username,self.__password)
            return True, 'success!'
        except Exception as err:
            return False, str(err)

    def get_popstatus(self):
        """
        得到邮箱状态,邮件封数和大小;
        :return:(邮件封数,邮件数据大小)
        """
        try:
            mail_status = self.__pop.stat()
            return mail_status
        except:
            conn_status = self.reconnect()
            if conn_status[0]:
                return self.__pop.stat()
            else:
                return conn_status[0], conn_status[1]

    def get_emails(self):
        """
        获取pop服务器邮箱中所有邮件
        :return: 邮件list:[[email1],[email2],...]
                 其中email也以列表出现，内容是email每
              行的byte类型数据。
        """
        email_list = []
        status = self.get_popstatus()
        for index in range(1, status[0]+1):
            try:
                email_list.append(self.__pop.retr(index))
            except Exception as err:
                email_list.append(str(err))
        return email_list

    def delete_email(self, index):
        """
        删除邮件;
        :param index:需要删除的邮件标号
        :return: (True/False,'success'/error message)
        """
        self.get_popstatus()
        try:
            self.__pop.dele(index)
            self.__pop.quit()
            self.reconnect()
            return True, 'success!'
        except Exception as err:
            return False, str(err)

    def quit(self):
        """
        退出连接;
        :return: True/False
        """
        try:
            self.__pop.quit()
            return True
        except:
            return False


if __name__ == '__main__':
    pass